package com.laundry.service.impl;

import com.laundry.dao.ClothesTypeDao;
import com.laundry.dao.OrderDao;
import com.laundry.dao.ServiceTypeDao;
import com.laundry.dao.UserDao;
import com.laundry.dto.OrderDTO;
import com.laundry.dto.ResultDTO;
import com.laundry.entity.ClothesType;
import com.laundry.entity.Order;
import com.laundry.entity.ServiceType;
import com.laundry.entity.User;
import com.laundry.service.OrderService;
import com.laundry.service.MessageService;
import com.laundry.vo.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private ServiceTypeDao serviceTypeDao;

    @Autowired
    private ClothesTypeDao clothesTypeDao;

    @Autowired
    private MessageService messageService;

    @Override
    public ResultDTO createOrder(OrderDTO orderDTO) {
        try {
            // 检查输入参数
            if (orderDTO == null) {
                return ResultDTO.error("订单数据不能为空");
            }

            Order order = new Order();
            order.setOrderNo(generateOrderNo());
            order.setUserId(orderDTO.getUserId());
            order.setServiceTypeId(orderDTO.getServiceTypeId());
            order.setClothesTypeId(orderDTO.getClothesTypeId());
            order.setQuantity(orderDTO.getQuantity());
            order.setTotalAmount(orderDTO.getTotalAmount());
            order.setPickupAddress(orderDTO.getPickupAddress());
            order.setDeliveryAddress(orderDTO.getDeliveryAddress());
            order.setStatus(0); // 待支付
            order.setPaymentMethod(orderDTO.getPaymentMethod());
            order.setPickupTime(orderDTO.getPickupTime());
            order.setRemark(orderDTO.getRemark());

            orderDao.save(order);

            return ResultDTO.success(order);
        } catch (Exception e) {
            e.printStackTrace(); // 打印异常栈
            return ResultDTO.error("创建订单失败：" + e.getMessage());
        }
    }

    @Override
    public ResultDTO getOrderList(Long userId, Integer status) {
        try {
            List<Order> orders;
            if (status != null) {
                orders = orderDao.findByUserIdAndStatus(userId, status);
            } else {
                orders = orderDao.findByUserId(userId);
            }

            // 转换为VO对象并填充关联信息
            List<OrderVO> orderVOs = convertToOrderVOList(orders);

            return ResultDTO.success(orderVOs);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.error("获取订单列表失败：" + e.getMessage());
        }
    }

    @Override
    public ResultDTO getOrderDetail(String orderNo) {
        try {
            Order order = orderDao.findByOrderNo(orderNo);
            if (order == null) {
                return ResultDTO.error("订单不存在");
            }

            // 使用新的便捷方法
            OrderVO orderVO = convertToOrderVO(order);
            if (orderVO != null) {
                return ResultDTO.success(orderVO);
            } else {
                return ResultDTO.error("订单信息转换失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.error("获取订单详情失败：" + e.getMessage());
        }
    }

    @Override
    public ResultDTO cancelOrder(String orderNo) {
        try {
            Order order = orderDao.findByOrderNo(orderNo);
            if (order == null) {
                return ResultDTO.error("订单不存在");
            }

            if (order.getStatus() > 1) {
                return ResultDTO.error("订单已处理，无法取消");
            }

            order.setStatus(4); // 已取消
            orderDao.save(order);

            return ResultDTO.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.error("取消订单失败：" + e.getMessage());
        }
    }

    @Override
    public ResultDTO payOrder(String orderNo, String paymentMethod) {
        try {
            Order order = orderDao.findByOrderNo(orderNo);
            if (order == null) {
                return ResultDTO.error("订单不存在");
            }

            if (order.getStatus() != 0) {
                return ResultDTO.error("订单状态不正确，无法支付");
            }

            order.setStatus(1); // 已支付待取件
            order.setPaymentMethod(paymentMethod);
            order.setPaymentTime(new Date());
            orderDao.save(order);

            return ResultDTO.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.error("支付订单失败：" + e.getMessage());
        }
    }

    @Override
    public void updateOrderStatus(String orderNo, Integer status) {
        Order order = orderDao.findByOrderNo(orderNo);
        if (order != null) {
            System.out.println("更新订单状态: 订单号=" + orderNo + ", 新状态=" + status); // 调试信息
            
            order.setStatus(status);
            
            // 根据状态设置相应的时间字段
            if (status == 1) {  // 已支付待取件
                order.setPaymentTime(new Date());
            } else if (status == 2) {  // 已取件处理中
                order.setPickupTime(new Date());
            } else if (status == 3) {  // 已完成
                order.setDeliveryTime(new Date());
                
                // 当订单完成时，自动发送通知
                sendOrderCompletionNotification(order);
            }
            
            orderDao.save(order);
        }
    }

    /**
     * 发送订单完成通知
     */
    private void sendOrderCompletionNotification(Order order) {
        try {
            // 构建通知消息
            String title = "订单已完成";
            String content = String.format("您的订单 %s 已完成。感谢您使用我们的服务！", order.getOrderNo());
            
            System.out.println("发送订单完成通知: 用户ID=" + order.getUserId() + 
                              ", 订单号=" + order.getOrderNo() + 
                              ", 标题=" + title); // 调试信息
            
            // 发送消息通知
            ResultDTO result = messageService.sendMessage(order.getUserId(), title, content);
            System.out.println("发送结果: " + (result.getCode() == 200 ? "成功" : "失败: " + result.getMessage())); // 调试信息
        } catch (Exception e) {
            // 记录错误但不影响主流程
            System.err.println("发送订单完成通知失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public List<Order> getAllOrders() {
        return orderDao.findAll();
    }

    @Override
    public List<Order> findByStatusIn(List<Integer> statusList) {
        if (statusList == null || statusList.isEmpty()) {
            return findAll();
        }
        return orderDao.findByStatusIn(statusList);
    }

    @Override
    public List<Order> findByUserIdAndStatusIn(Long userId, List<Integer> statusList) {
        if (statusList == null || statusList.isEmpty()) {
            return findByUserId(userId);
        }
        return orderDao.findByUserIdAndStatusIn(userId, statusList);
    }

    @Override
    public List<Order> findAll() {
        return orderDao.findAll();
    }

    @Override
    public List<Order> findByUserId(Long userId) {
        return orderDao.findByUserId(userId);
    }

    @Override
    public ResultDTO getAdminOrderList() {
        try {
            List<Order> orders = orderDao.findAll();

            // 转换为VO对象并填充关联信息
            List<OrderVO> orderVOs = convertToOrderVOList(orders);

            return ResultDTO.success(orderVOs);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.error("获取订单列表失败：" + e.getMessage());
        }
    }

    @Override
    public OrderVO getOrderDetail(Long id) {
        Order order = orderDao.findById(id).orElse(null);
        if (order == null) {
            return null;
        }
        return convertToOrderVO(order);
    }

    @Override
    public List<OrderVO> convertToOrderVOList(List<Order> orders) {
        if (orders == null || orders.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取所有服务类型和衣物类型
        List<ServiceType> serviceTypes = serviceTypeDao.findAll();
        List<ClothesType> clothesTypes = clothesTypeDao.findAll();
        
        // 打印调试信息，查看服务类型和衣物类型数据
        System.out.println("服务类型数量: " + serviceTypes.size());
        for(ServiceType st : serviceTypes) {
            System.out.println("服务类型: " + st.getId() + " - " + st.getName());
        }
        
        System.out.println("衣物类型数量: " + clothesTypes.size());
        for(ClothesType ct : clothesTypes) {
            System.out.println("衣物类型: " + ct.getId() + " - " + ct.getName());
        }
        
        // 创建映射以提高查询效率
        Map<Long, String> serviceTypeMap = serviceTypes.stream()
                .collect(Collectors.toMap(ServiceType::getId, ServiceType::getName));
        Map<Long, String> clothesTypeMap = clothesTypes.stream()
                .collect(Collectors.toMap(ClothesType::getId, ClothesType::getName));
        
        // 转换订单列表
        List<OrderVO> result = orders.stream().map(order -> {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(order, orderVO);
            
            // 设置服务类型名称
            String serviceTypeName = serviceTypeMap.getOrDefault(order.getServiceTypeId(), "未知服务");
            orderVO.setServiceTypeName(serviceTypeName);
            orderVO.setServiceTypes(serviceTypeName);
            
            // 设置衣物类型名称
            String clothesTypeName = clothesTypeMap.getOrDefault(order.getClothesTypeId(), "未知衣物");
            orderVO.setClothesTypeName(clothesTypeName);
            orderVO.setClothesTypes(clothesTypeName);
            
            System.out.println("订单ID: " + order.getId() + 
                              ", 服务类型ID: " + order.getServiceTypeId() +
                              ", 服务类型名称: " + serviceTypeName +
                              ", 衣物类型ID: " + order.getClothesTypeId() +
                              ", 衣物类型名称: " + clothesTypeName);
            
            return orderVO;
        }).collect(Collectors.toList());
        
        return result;
    }
    
    @Override
    public OrderVO convertToOrderVO(Order order) {
        if (order == null) {
            return null;
        }
        
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order, orderVO);
        
        // 获取服务类型名称
        ServiceType serviceType = serviceTypeDao.findById(order.getServiceTypeId()).orElse(null);
        if (serviceType != null) {
            orderVO.setServiceTypeName(serviceType.getName());
        } else {
            orderVO.setServiceTypeName("未知服务");
        }
        
        // 获取衣物类型名称
        ClothesType clothesType = clothesTypeDao.findById(order.getClothesTypeId()).orElse(null);
        if (clothesType != null) {
            orderVO.setClothesTypeName(clothesType.getName());
        } else {
            orderVO.setClothesTypeName("未知衣物");
        }
        
        return orderVO;
    }
    
    // 生成订单号
    private String generateOrderNo() {
        return "OD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 4);
    }

    @Override
    public BigDecimal calculateTodayIncome() {
        // 获取今天的开始时间
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date startOfDay = cal.getTime();
        
        // 获取今天的结束时间
        cal.add(Calendar.DAY_OF_MONTH, 1);
        Date endOfDay = cal.getTime();
        
        System.out.println("计算今日收入 - 开始时间: " + startOfDay + ", 结束时间: " + endOfDay);
        
        // 使用支付时间而不是创建时间
        List<Order> todayPaidOrders = orderDao.findByPaymentTimeBetweenAndStatusGreaterThan(
            startOfDay, endOfDay, 0);
        
        System.out.println("找到的今日已支付订单数量: " + todayPaidOrders.size());
        
        // 计算总收入
        BigDecimal income = BigDecimal.ZERO;
        for (Order order : todayPaidOrders) {
            if (order.getTotalAmount() != null) {
                income = income.add(order.getTotalAmount());
                System.out.println("订单: " + order.getOrderNo() + ", 金额: " + order.getTotalAmount());
            }
        }
        
        System.out.println("计算出的今日总收入: " + income);
        return income;
    }

    @Override
    public Order findByOrderNo(String orderNo) {
        return orderDao.findByOrderNo(orderNo);
    }

    @Override
    public List<Order> findByStatus(Integer status) {
        return orderDao.findByStatus(status);
    }

    @Override
    public List<Order> findByOrderNoAndStatus(String orderNo, Integer status) {
        return orderDao.findByOrderNoContainingAndStatus(orderNo, status);
    }
} 